package com.neusoft.elm.framework;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.ObjectMapper;
/**
* 自定义前端控制器 拦截url格式要求： /api/控制器类名/控制器方法名
*/
@WebServlet(urlPatterns = {"/*"})
public class DispatcherServlet extends HttpServlet {
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
	ServletException, IOException {
	 //中文编码处理
	 request.setCharacterEncoding("utf-8");
	 response.setCharacterEncoding("utf-8");
	 response.setContentType("application/json;charset=utf-8");

	 //获取客户端请求路径(/api/HelloController/say)
	 String path = request.getRequestURI(); // 改用 getRequestURI() 而不是 getServletPath()
	 System.out.println("完整请求URI: " + path);
	 System.out.println("ServletPath: " + request.getServletPath());
	 System.out.println("PathInfo: " + request.getPathInfo());

	 // 移除项目上下文路径
	 String contextPath = request.getContextPath();
	 if (path.startsWith(contextPath)) {
	     path = path.substring(contextPath.length());
	 }
	 System.out.println("移除上下文后路径: " + path);

	 // 移除/api前缀，获取实际的Controller路径
	 if (path.startsWith("/api/")) {
	     path = path.substring(4); // 移除"/api"前缀
	 } else if (path.equals("/api")) {
	     // 如果只是访问 /api，返回API说明
	     response.setContentType("text/html;charset=utf-8");
	     PrintWriter out = response.getWriter();
	     out.print("<h1>ELM API 服务</h1><p>请访问具体的API接口，格式：/api/控制器类名/方法名</p>");
	     out.close();
	     return;
	 }
 System.out.println("最终处理路径: " + path);

     // 如果是根路径，直接转发到index.html
     if (path == null || path.equals("/")) {
         response.sendRedirect(request.getContextPath() + "/index.html");
         return;
     }

     // 如果是静态资源，让默认servlet处理
     if (path.equals("/index.html") ||
         path.startsWith("/css/") || path.startsWith("/js/") || path.startsWith("/images/") ||
         path.endsWith(".html") || path.endsWith(".css") || path.endsWith(".js") ||
         path.endsWith(".png") || path.endsWith(".jpg") || path.endsWith(".ico")) {
         // 让默认servlet处理静态资源
         request.getRequestDispatcher(path).forward(request, response);
         return;
     }

     // 验证是否为Controller请求格式
     int lastSlashIndex = path.lastIndexOf("/");
     if (path.isEmpty() || path.equals("/") || lastSlashIndex <= 0) {
         response.setStatus(HttpServletResponse.SC_NOT_FOUND);
         PrintWriter out = response.getWriter();
         out.print("{\"error\":\"请求路径格式错误，正确格式：/api/控制器类名/方法名\"}");
         out.close();
         return;
     }

     //根据请求路径，将Controller的类名和方法名解析出来
     String className = path.substring(1, lastSlashIndex);
     String methodName = path.substring(lastSlashIndex + 1);

	 System.out.println("解析出的类名: " + className);
	 System.out.println("解析出的方法名: " + methodName);

	 // 验证类名和方法名不为空
	 if (className.isEmpty() || methodName.isEmpty()) {
	     response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
	     PrintWriter out = response.getWriter();
	     out.print("{\"error\":\"控制器类名或方法名不能为空\"}");
	     out.close();
	     return;
	 }

	 PrintWriter out = null;
	 //判断请求路径，根据不同的请求，分发给不同的业务处理器
	 try{
	 //通过Controller类全名获取此类的所有信息
	 Class clazz = Class.forName("com.neusoft.elm.controller."+className);
	 //创建Controller类的对象
	 Object controller = clazz.newInstance();
	 //获取Controller类对象中的方法
	 Method method = clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
	 //调用上面获取的方法
	 Object result = method.invoke(controller, request, response);
	 //获取向客户端响应的输出流
	 out = response.getWriter();
	 ObjectMapper om = new ObjectMapper();
	 //向客户端响应json数据
	 out.print(om.writeValueAsString(result));

	 }catch(Exception e){
	 e.printStackTrace();
	 System.out.println("DispatcherServlet信息：请求url："+path);
	 System.out.println("DispatcherServlet信息：类名："+className+"\t方法名："+methodName);
	 // 向客户端返回错误信息
	 if (out == null) {
	     out = response.getWriter();
	 }
	 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
	 out.print("{\"error\":\"服务器内部错误：" + e.getMessage() + "\"}");
	 }finally {
	 if (out != null) {
	     out.close();
	 }
	 }
	 }
	 @Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
	ServletException, IOException {
	 doPost(request,response);
	 }
	}